package com.baijiaoxi.common.utils.jdk;

import com.baijiaoxi.common.constant.DateTime;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 用于生成按日期的序列号
 */
@Slf4j
public class DateCounter {
    private Map<String, AtomicInteger> map = new HashMap<>();
    private PeriodUnit periodUnit;
    private ScheduledExecutorService executorService;

    public enum PeriodUnit {
        DAY(DateTime.SHORT_DATE_NOSPLIT),
        MONTH(DateTime.MONTH_NOSPLIT),
        YEAR(DateTime.YEAR_NOSPLIT);

        PeriodUnit(SimpleDateFormat dateFormat) {
            this.dateFormat = dateFormat;
        }

        private SimpleDateFormat dateFormat;


    }

    public DateCounter() {
        this.periodUnit = PeriodUnit.DAY;
        initCounter(0);
    }

    public DateCounter(int index) {
        this.periodUnit = PeriodUnit.DAY;
        initCounter(index);
    }

    public DateCounter(PeriodUnit periodUnit, int index) {
        this.periodUnit = periodUnit;
        initCounter(index);
    }


    public int get() {
        String dateStr = periodUnit.dateFormat.format(new Date());
        return map.get(dateStr).incrementAndGet();
    }

    public String get(int length) {
        int index = get();
        String format = "%0" + length + "d";
        return String.format(format, index);
    }

    private void initCounter(int index) {
        executorService = Executors.newScheduledThreadPool(1);
        initCounter(periodUnit.dateFormat.format(new Date()), index);
        // 执行任务，然后每天执行一次
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    Date now = new Date();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(now);
                    calendar.add(Calendar.DATE, 1);
                    Date newDate = calendar.getTime();
                    initCounter(periodUnit.dateFormat.format(newDate), 0);
                } catch (Exception e) {
                    log.error("周期初始化下一日期计数器失败", e);
                }
            }
        }, 0, 1, TimeUnit.DAYS);
    }

    private void initCounter(String dateStr, int index) {
        if (!map.containsKey(dateStr)) {
            AtomicInteger atomicInteger = new AtomicInteger(index);
            map.put(dateStr, atomicInteger);
            log.info("日期计数器:{}初始化成功", dateStr);
        }
    }

}
